﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine.SceneManagement;
using System.Reflection;
using UnityEngine.UI;

public static class PrefabTool
{
    [MenuItem("Assets/Custom/PrefabTool/PrintGuid")]
    public static void PrintGuid()
    {
//        string log = "";
        EditorCommonTool.ProcessSelectionObjs("*", (assetPath) =>
            {
                string guid = AssetDatabase.AssetPathToGUID(assetPath);
                Debug.LogError(guid);
            });


    }

    [MenuItem("Assets/Custom/PrefabTool/PrintDependencies")]
    public static void PrintDependencies()
    {
        
        string log = "";
        EditorCommonTool.ProcessSelectionObjs("*", (assetPath) =>
            {
                if(assetPath.EndsWith(".meta"))
                {
                    return;
                }

                Dictionary<string, string[]> dMap = new Dictionary<string, string[]>();
                Queue<string> q = new Queue<string>();
                q.Enqueue(assetPath);

                while(q.Count > 0)
                {
                    string s = q.Dequeue();
                    if(dMap.ContainsKey(s))
                    {
                        continue;
                    }

                    string[] ds = AssetDatabase.GetDependencies(s, false);
                    if(ds.Length > 0)
                    {
                        dMap.Add(s, ds);
                        for(int i = 0; i < ds.Length; i++)
                        {
                            if(!dMap.ContainsKey(ds[i]))
                            {
                                q.Enqueue(ds[i]);
                            }
                        }
                    }
                }

                foreach(var entry in dMap)
                {
                    log += entry.Key + "\n";
                    for(int i = 0; i < entry.Value.Length; i++)
                    {
                        log += "\t" + entry.Value[i] + "\n";
                    }
                }
            });

        CommonUtil.stringToFile("dependence_log.txt", log);
    }

    [MenuItem("Custom/PrefabTool/ChangeToUI2DSpriteEx")]
    public static void ChangeToUI2DSpriteEx()
    {
        string oldComponentStr = "m_Script: {fileID: 11500000, guid: e96b31ce75e592f45a1cff563a4869db, type: 3}";
        string newComponentStr = "m_Script: {fileID: 11500000, guid: ce931f886b3e740bcbc50f13e06ac6d0, type: 3}";

        ChangeComponent(oldComponentStr, newComponentStr);
    }


    [MenuItem("Custom/PrefabTool/ChangeToUIButtonEx")]
    public static void ChangeToUIButtonEx()
    {
        string oldComponentStr = "m_Script: {fileID: 11500000, guid: 1fdca5042b1d12a4890ec1bd4f04290d, type: 3}";
        string newComponentStr = "m_Script: {fileID: 11500000, guid: cbdced7dc50a643b29960fb809d7a128, type: 3}";

        ChangeComponent(oldComponentStr, newComponentStr);
    }

    [MenuItem("Custom/PrefabTool/ChangeToUIPlaySoundEx")]
    public static void ChangeToUIPlaySoundEx()
    {
        string oldComponentStr = "m_Script: {fileID: 11500000, guid: 7d44bc69c2ca5f943b845318866dc1bd, type: 3}";
        string newComponentStr = "m_Script: {fileID: 11500000, guid: ce8139956a1ba4f5e9af9c49dd357f81, type: 3}";

        ChangeComponent(oldComponentStr, newComponentStr);
    }

    [MenuItem("Custom/PrefabTool/ChangeToUILabelEx")]
    public static void ChangeToUILabelEx()
    {
        string oldComponentStr = "m_Script: {fileID: 11500000, guid: e9d0b5f3bbe925a408bd595c79d0bf63, type: 3}";
        string newComponentStr = "m_Script: {fileID: 11500000, guid: 97d22ff608e354bdc92b9efe2758b511, type: 3}";

        ChangeComponent(oldComponentStr, newComponentStr);
    }

    [MenuItem("Custom/PrefabTool/ChangeToUILabel")]
    public static void ChangeToUILabel()
    {
        string newComponentStr = "m_Script: {fileID: 11500000, guid: e9d0b5f3bbe925a408bd595c79d0bf63, type: 3}";
        string oldComponentStr = "m_Script: {fileID: 11500000, guid: 97d22ff608e354bdc92b9efe2758b511, type: 3}";

        ChangeComponent(oldComponentStr, newComponentStr);
    }
    static string componentGuid0;
    [MenuItem("Assets/Custom/PrefabTool/ChangeComponentStep1")]
    public static void ChangeComponentStep1()
    {
        string path = AssetDatabase.GetAssetPath(Selection.objects[0]);
        componentGuid0 = AssetDatabase.AssetPathToGUID(path);
    }

    [MenuItem("Assets/Custom/PrefabTool/ChangeComponentStep2")]
    public static void ChangeComponentStep2()
    {
        string path = AssetDatabase.GetAssetPath(Selection.objects[0]);
        string componentGuid1 = AssetDatabase.AssetPathToGUID(path);
        if(string.IsNullOrEmpty(componentGuid0))
        {
            return;
        }

        string oldComponentStr = "m_Script: {fileID: 11500000, guid: " + componentGuid0 + ", type: 3}";
        string newComponentStr = "m_Script: {fileID: 11500000, guid: " + componentGuid1 + ", type: 3}";
        ChangeComponent(oldComponentStr, newComponentStr);
        componentGuid0 = null;
    }

	[MenuItem("Assets/Custom/PrefabTool/FindReference")]
	public static void FindReference()
	{
		string path = AssetDatabase.GetAssetPath(Selection.activeObject);
		string componentGuid1 = AssetDatabase.AssetPathToGUID(path);
		if(string.IsNullOrEmpty(componentGuid1))
		{
			return;
		}
			
		FindReference2(componentGuid1);
	}

//    [MenuItem("Custom/OldProject/Modify/ChangeToEvonyImage")]
//    public static void ConvertImageToEvonyImage()
//    {
//        string[] prefabDirs = new string[]{"Assets/"};
//        for(int v = 0; v < prefabDirs.Length; v++)
//        {
//            string[] paths = Directory.GetFiles(prefabDirs[v], "*.prefab", SearchOption.AllDirectories);
//            for(int i = 0; i < paths.Length; i++)
//            {
//                bool isNeedSave = false;
//
//                string path = paths[i];
//                string str = File.ReadAllText(path);
//                string oldStr = "m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}";
//                if(str.IndexOf(oldStr) >= 0)
//                {
//                    string newStr = str.Replace(oldStr, "m_Script: {fileID: 11500000, guid: 009d33ff165d24051a3492e477b62966, type: 3}");
//                    File.WriteAllText(path, newStr);
//                }
//            }
//        }
//
//        AssetDatabase.SaveAssets();
//    }

    static void ChangeComponent(string oldComponentStr, string newComponentStr)
    {
        string[] prefabDirs = new string[]{ResourcesEx.BundleResDir + "/"};
        for(int v = 0; v < prefabDirs.Length; v++)
        {
            string[] paths = System.IO.Directory.GetFiles(prefabDirs[v], "*.prefab", System.IO.SearchOption.AllDirectories);
            for(int i = 0; i < paths.Length; i++)
            {
                string path = paths[i];
                string str = System.IO.File.ReadAllText(path);
                if(str.IndexOf(oldComponentStr) >= 0)
                {
                    string newStr = str.Replace(oldComponentStr, newComponentStr);
                    System.IO.File.WriteAllText(path, newStr);
                }
            }
        }

        AssetDatabase.Refresh();
        AssetDatabase.SaveAssets();
    }

	static void FindReference2(string guid)
	{
		string log = "";
        string[] prefabDirs = new string[]{"Assets" + "/"};
		for(int v = 0; v < prefabDirs.Length; v++)
		{
			string[] paths = System.IO.Directory.GetFiles(prefabDirs[v], "*", System.IO.SearchOption.AllDirectories);
			for(int i = 0; i < paths.Length; i++)
			{
				string path = paths[i];
                if (path.EndsWith(".meta") || path.EndsWith(".mat") || path.EndsWith(".prefab"))
                {
                    string str = System.IO.File.ReadAllText(path);
                    if(str.IndexOf(guid) >= 0)
                    {
                        log += path + "\n";
                    }
                }
			}
		}

		Debug.LogError(log);
	}

    static SpriteEx GetSpriteEx(Sprite sprite)
    {
        ResourcesEx.EnableSpriteSheet(true);
        string spritePath = AssetDatabase.GetAssetPath(sprite);
        spritePath = spritePath.Replace(ConfigTool.bundleDir[0] + "/", "");
        string ext = System.IO.Path.GetExtension(spritePath);
        if (string.IsNullOrEmpty(ext))
        {
            return null;
        }
        spritePath = spritePath.Replace(ext, "");
		SpriteEx spriteEx = ResourcesEx.LoadSpriteEx(spritePath, false);
        return spriteEx;
    }

    static void ReferenceSceneToSpriteSheet()
    {
        for (int i = 0; i < EditorBuildSettings.scenes.Length; i++)
        {
            string scenePath = EditorBuildSettings.scenes[i].path;
            Scene scene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Additive);

            GameObject[] objs = scene.GetRootGameObjects();
            bool needSave = false;

            for (int j = 0; j < objs.Length; j++)
            {
                bool ret = ObjReferenceToSpriteSheet(objs[j]);
                needSave |= ret;

                // Debug.Log("ReferenceSceneToSpriteSheet_2: " + objs[j].name + "  " + objs[j].GetComponentsInChildren<UI2DSpriteEx>(true).Length + "  " + objs[j].GetComponentsInChildren<UIButtonEx>(true).Length);

            }
            // Debug.Log("ReferenceSceneToSpriteSheet: " + scenePath + "  " + objs.Length + "  " + GameObject.FindObjectsOfType<GameObject>().Length + "  " + needSave);

            if (needSave)
            {
                EditorSceneManager.SaveScene(scene);
            }

            EditorSceneManager.CloseScene(scene, true);
        }
    }

    static bool ObjReferenceToSpriteSheet(Object obj)
    {
        if (obj == null)
        {
            return false;
        }
        
        if(obj is AnimationClip)
        {
            setAnimReferenceToSpriteSheet(obj as AnimationClip);
            return false;
        }
        else if(obj is GameObject)
        {
            GameObject gameObj = obj as GameObject;
            bool needSave = false;
            SpriteRenderer[] renders = gameObj.GetComponentsInChildren<SpriteRenderer>(true);
            for (int j = 0; j < renders.Length; j++)
            {
                SpriteRenderer render = renders[j];
                if (render.sprite == null)
                {
                    continue;
                }
                SpriteEx spriteEx = GetSpriteEx(render.sprite);
                if (spriteEx != null && spriteEx.sheetInfo != null)
                {
                    render.sprite = spriteEx.sprite;
                    if (spriteEx.sheetInfo.spriteMat != null)
                    {
                        render.sharedMaterial = spriteEx.sheetInfo.spriteMat;
                    }
                    needSave = true;
                }
            }
            UI2DSpriteEx[] spriteComs = gameObj.GetComponentsInChildren<UI2DSpriteEx>(true);
            for (int j = 0; j < spriteComs.Length; j++)
            {
                UI2DSpriteEx spriteUI = spriteComs[j];
                if (spriteUI.sprite2D == null)
                {
                    continue;
                }
                SpriteEx spriteEx = GetSpriteEx(spriteUI.sprite2D);
    //            if (spriteUI.sprite2D != null && spriteUI.sprite2D.name.Contains("quality") && spriteEx == null)
    //            {
    //                Debug.LogError("not found");
    //                //                    spriteEx = GetSpriteEx(spriteUI.sprite2D);
    //            }
                if (spriteEx != null && spriteEx.sheetInfo != null)
                {
                    spriteUI.SetSprite(spriteEx);
                    needSave = true;
                }
            }
            UIButtonEx[] buttonComs = gameObj.GetComponentsInChildren<UIButtonEx>(true);
            for (int j = 0; j < buttonComs.Length; j++)
            {
                UIButtonEx buttonUI = buttonComs[j];
                //                UI2DSpriteEx uisprite = buttonUI.GetComponent<UI2DSpriteEx>();
                //                if(uisprite != null && uisprite.spriteEx != null && uisprite.spriteEx.sheetInfo != null)
                //                {
                //                    buttonUI.normalSpriteEx = uisprite.spriteEx;
                //                    needSave = true;
                //                }
                SpriteEx spriteEx = GetSpriteEx(buttonUI.disabledSprite2D);
                if (spriteEx != null && spriteEx.sheetInfo != null)
                {
                    buttonUI.disabledSpriteEx = spriteEx;
                    buttonUI.disabledSprite2D = spriteEx.sprite;
                    needSave = true;
                }
                spriteEx = GetSpriteEx(buttonUI.pressedSprite2D);
                if (spriteEx != null && spriteEx.sheetInfo != null)
                {
                    buttonUI.pressedSpriteEx = spriteEx;
                    buttonUI.pressedSprite2D = spriteEx.sprite;
                    needSave = true;
                }
                spriteEx = GetSpriteEx(buttonUI.hoverSprite2D);
                if (spriteEx != null && spriteEx.sheetInfo != null)
                {
                    buttonUI.hoverSpriteEx = spriteEx;
                    buttonUI.hoverSprite2D = spriteEx.sprite;
                    needSave = true;
                }
            }

            UI2DSpriteAnimationEx[] animComs = gameObj.GetComponentsInChildren<UI2DSpriteAnimationEx>(true);
            for (int j = 0; j < animComs.Length; j++)
            {
                UI2DSpriteAnimationEx animCom = animComs[j];

                for (int i = 0; i < animCom.frames.Length; i++)
                {
                    SpriteEx spriteEx = animCom.frames[i];
                    SpriteEx newSpriteEx = GetSpriteEx(spriteEx.sprite);
                    if (newSpriteEx != null && newSpriteEx.sheetInfo != null)
                    {
                        animCom.frames[i] = newSpriteEx;
                        needSave = true;
                    }
                }
            }

            Image[] images = gameObj.GetComponentsInChildren<Image> (true);
			for (int j = 0; j < images.Length; j++) {
				Image image = images [j];
                
				Sprite sprite = image.sprite;
				if (sprite != null) {
					// string spritePath = AssetDatabase.GetAssetPath (sprite);
					// string newSpriteName = spritePath.Replace (resPath + "/", "");
					// string spriteSheetName = spriteSheetConfig.getSpriteSheetName (newSpriteName);
					// string spriteSheetPath = "";
					// Sprite tempSprite = getSprite (resPath, ref spriteSheetMap, spriteSheetName, newSpriteName, sprite.name, ref spriteSheetPath, target);
                    SpriteEx tempSprite = GetSpriteEx(sprite);
					if (tempSprite != null) {
                        if(image is ZImage)
                        {
                            ZImage zimage = image as ZImage;
                            zimage.SetSprite(tempSprite);
                        }
                        else
                        {
                            image.sprite = tempSprite.sprite;
                        }
						
						// Material material = AssetDatabase.LoadAssetAtPath (spriteSheetPath + ResourcesEx.spriteSheetUiMaterialSuffix + ".mat", typeof(Material)) as Material;
						// if (material != null) {
						// 	image.material = material;
						// }
						needSave = true;
					}
				}
			}
			Button[] buttons = gameObj.GetComponentsInChildren<Button> (true);
			for (int j = 0; j < buttons.Length; j++) {
				Button button = buttons [j];
				if (button.transition == Selectable.Transition.SpriteSwap) {
					bool settedMaterial = false;
					SpriteState state = button.spriteState;
					Sprite sprite = state.pressedSprite;
					if (sprite != null) {
						// string spritePath = AssetDatabase.GetAssetPath (sprite);
						// string newSpriteName = spritePath.Replace (resPath + "/", "");
						// string spriteSheetName = spriteSheetConfig.getSpriteSheetName (newSpriteName);
						// string spriteSheetPath = "";
						// Sprite tempSprite = getSprite (resPath, ref spriteSheetMap, spriteSheetName, newSpriteName, sprite.name, ref spriteSheetPath, target);
                        SpriteEx tempSprite = GetSpriteEx(sprite);
						if (tempSprite != null) {
							state.pressedSprite = tempSprite.sprite;
							// Material material = AssetDatabase.LoadAssetAtPath (spriteSheetPath + ResourcesEx.spriteSheetUiMaterialSuffix + ".mat", typeof(Material)) as Material;
							// if (material != null) {
							// 	button.image.material = material;
							// }
							// settedMaterial = true;
							needSave = true;
						}
					}
					sprite = state.disabledSprite;
					if (sprite != null) {
						// string spritePath = AssetDatabase.GetAssetPath (sprite);
						// string newSpriteName = spritePath.Replace (resPath + "/", "");
						// string spriteSheetName = spriteSheetConfig.getSpriteSheetName (newSpriteName);
						// string spriteSheetPath = "";
						// Sprite tempSprite = getSprite (resPath, ref spriteSheetMap, spriteSheetName, newSpriteName, sprite.name, ref spriteSheetPath, target);
                        SpriteEx tempSprite = GetSpriteEx(sprite);
						if (tempSprite != null) {
							state.disabledSprite = tempSprite.sprite;
							// if (!settedMaterial) {
							// 	Material material = AssetDatabase.LoadAssetAtPath (spriteSheetPath + ResourcesEx.spriteSheetUiMaterialSuffix + ".mat", typeof(Material)) as Material;
							// 	if (material != null) {
							// 		button.image.material = material;
							// 	}
							// 	settedMaterial = true;
							// }
							needSave = true;
						}
					}
					sprite = state.highlightedSprite;
					if (sprite != null) {
						// string spritePath = AssetDatabase.GetAssetPath (sprite);
						// string newSpriteName = spritePath.Replace (resPath + "/", "");
						// string spriteSheetName = spriteSheetConfig.getSpriteSheetName (newSpriteName);
						// string spriteSheetPath = "";
						// Sprite tempSprite = getSprite (resPath, ref spriteSheetMap, spriteSheetName, newSpriteName, sprite.name, ref spriteSheetPath, target);
                        SpriteEx tempSprite = GetSpriteEx(sprite);
						if (tempSprite != null) {
							state.highlightedSprite = tempSprite.sprite;
							// if (!settedMaterial) {
							// 	Material material = AssetDatabase.LoadAssetAtPath (spriteSheetPath + ResourcesEx.spriteSheetUiMaterialSuffix + ".mat", typeof(Material)) as Material;
							// 	if (material != null) {
							// 		button.image.material = material;
							// 	}
							// 	settedMaterial = true;
							// }
							needSave = true;
						}
					}
					if (settedMaterial) {
						button.spriteState = state;
					}
				}
			}

            MonoBehaviour[] behComs = gameObj.GetComponentsInChildren<MonoBehaviour>(true);
            for (int j = 0; j < behComs.Length; j++)
            {
                MonoBehaviour b = behComs[j];
                if (b == null || b is UI2DSpriteEx || b is UIButtonEx)
                {
                    continue;
                }
                System.Type t = b.GetType();
                System.Reflection.FieldInfo[] fields = t.GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
                for (int k = 0; k < fields.Length; k++)
                {
                    System.Reflection.FieldInfo field = fields[k];
                    if (field.FieldType == typeof(SpriteEx))
                    {
                        SpriteEx spriteEx = field.GetValue(b) as SpriteEx;
                        if (spriteEx.sheetInfo == null)
                        {
                            SpriteEx newSpriteEx = GetSpriteEx(spriteEx.sprite);
                            if (newSpriteEx != null && newSpriteEx.sheetInfo != null)
                            {
                                field.SetValue(b, newSpriteEx);
                                needSave = true;
                            }
                        }
                    }
                    else if (field.FieldType == typeof(SpriteEx[]))
                    {
                        bool changed = false;
                        SpriteEx[] spriteExs = field.GetValue(b) as SpriteEx[];
                        for (int m = 0; m < spriteExs.Length; m++)
                        {
                            SpriteEx sp = spriteExs[m];
                            if (sp.sheetInfo == null)
                            {
                                SpriteEx newSpriteEx = GetSpriteEx(sp.sprite);
                                if (newSpriteEx != null && newSpriteEx.sheetInfo != null)
                                {
                                    spriteExs[m] = newSpriteEx;
                                    needSave = true;
                                    changed = true;
                                }
                            }
                        }

                        if (changed)
                        {
                            field.SetValue(b, spriteExs);
                        }
                    }
                }
            }

            return needSave;
        }

        
        return false;
    }

	static void ReferencePrefabToSpriteSheet()
	{
        string[] paths = System.IO.Directory.GetFiles(ResourcesEx.BundleResDir + "/", "*.prefab", System.IO.SearchOption.AllDirectories);
		for (int i = 0; i < paths.Length; i++)
		{
			string path = paths[i];


			GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
			bool needInstance = true;
			if(needInstance)
			{
				GameObject obj = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
				if (obj == null)
				{
					Debug.LogError("load prefab failed: " + path);
					continue;
				}
				bool needSave = ObjReferenceToSpriteSheet(obj);
				if (needSave)
				{
					//                PropertyModification[] modifies = PrefabUtility.GetPropertyModifications(obj);
					//                PrefabUtility.SetPropertyModifications(prefab, modifies);
					PrefabUtility.ReplacePrefab(obj, prefab, ReplacePrefabOptions.Default);
//                    PrefabUtility.SavePrefabAsset(obj);
				}
				GameObject.DestroyImmediate(obj);
			}
			else
			{
				bool needSave = ObjReferenceToSpriteSheet(prefab);
				if (needSave)
				{
//					EditorUtility.SetDirty(prefab);
//                    Undo.RecordObject(prefab, "ReferencePrefabToSpriteSheet");
                    PrefabUtility.SavePrefabAsset(prefab);
				}
			}
		}
	}

    static void ReferenceAnimToSpriteSheet()
	{
        string[] paths = System.IO.Directory.GetFiles(ResourcesEx.BundleResDir + "/", "*.anim", System.IO.SearchOption.AllDirectories);
		for (int i = 0; i < paths.Length; i++)
		{
			string path = paths[i];
			AnimationClip animClip = AssetDatabase.LoadAssetAtPath<AnimationClip>(path);
            bool needSave = ObjReferenceToSpriteSheet(animClip);
		}

        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
	}

	public static void setAnimReferenceToSpriteSheet (AnimationClip clip)
	{
        EditorCurveBinding[] curveBindings = AnimationUtility.GetObjectReferenceCurveBindings (clip);
        for (int j = 0; j < curveBindings.Length; j++)
        {
            if (curveBindings [j].propertyName == "m_Sprite")
            {
                System.Type t = curveBindings[j].type;

                bool isNeedSave = false;
                ObjectReferenceKeyframe[] keyFrame = AnimationUtility.GetObjectReferenceCurve (clip, curveBindings [j]);
                string preTexName = null;
                SortedDictionary<float, Texture> textureMap = new SortedDictionary<float, Texture>();
                for (int k = 0; k < keyFrame.Length; k++)
                {
                    Sprite sprite = (Sprite)keyFrame [k].value;
                    if(sprite != null)
                    {
                        // string spritePath = AssetDatabase.GetAssetPath (sprite);
                        // string newSpriteName = spritePath.Replace (resPath + "/", "");
                        // string spriteSheetName = spriteSheetConfig.getSpriteSheetName (newSpriteName);
                        // string spriteSheetPath = "";
                        // Sprite tempSprite = getSprite (resPath, ref spriteSheetMap, spriteSheetName, newSpriteName, sprite.name, ref spriteSheetPath, target);


                        Sprite tempSprite = GetSpriteEx(sprite).sprite;
                        if (tempSprite != null && tempSprite != sprite)
                        {
                            isNeedSave = true;
                            keyFrame[k].value = tempSprite;	
                            if(preTexName != tempSprite.texture.name)
                            {
                                textureMap.Add(keyFrame[k].time, tempSprite.texture);
                                preTexName = tempSprite.texture.name;
                            }
                        }
                        else
                        {
                            Debug.LogError("getSprite failed: " + sprite);
                        }
                    }
                }

                if (isNeedSave)
                {
                    // SortedDictionary<float, Texture>.Enumerator e3 = textureMap.GetEnumerator();
                    // e3.MoveNext();
                    // string spriteSheetName = e3.Current.Value.name;
                    // string matPath = resPath + "/" + EditorCommonTool.getSheetDirName(target) + "/" + spriteSheetName + "/" + spriteSheetName + ResourcesEx.spriteSheetMaterialSuffix + ".mat";
                    // if(File.Exists(matPath))
                    // {
                    //     ObjectReferenceKeyframe[] matKeyFrames = new ObjectReferenceKeyframe[textureMap.Count];
                    //     SortedDictionary<float, Texture>.Enumerator e2 = textureMap.GetEnumerator();
                    //     int k = 0;
                    //     while(e2.MoveNext())
                    //     {
                    //         spriteSheetName = e2.Current.Value.name;
                    //         string matPath2 = null;
                    //         if(t == typeof(SpriteRenderer))
                    //         {
                    //             matPath2 = resPath + "/" + EditorCommonTool.getSheetDirName(target) + "/" + spriteSheetName + "/" + spriteSheetName + ResourcesEx.spriteSheetMaterialSuffix + ".mat";
                    //         }
                    //         else
                    //         {
                    //             matPath2 = resPath + "/" + EditorCommonTool.getSheetDirName(target) + "/" + spriteSheetName + "/" + spriteSheetName + ResourcesEx.spriteSheetUiMaterialSuffix + ".mat";
                    //         }

                    //         Object obj = AssetDatabase.LoadAssetAtPath(matPath2, typeof(Material));
                    //         matKeyFrames[k] = new ObjectReferenceKeyframe ();
                    //         matKeyFrames[k].time = e2.Current.Key;
                    //         matKeyFrames[k].value = obj;
                    //         k++;
                    //     }
                        
                    //     EditorCurveBinding curveBinding2 = new EditorCurveBinding();
                    //     curveBinding2.type = t;
                    //     curveBinding2.path = curveBindings [j].path;
                    //     if(t == typeof(SpriteRenderer))
                    //     {
                    //         curveBinding2.propertyName = "m_Materials.Array.data[0]";
                    //     }
                    //     else
                    //     {
                    //         curveBinding2.propertyName = "m_Material";
                    //     }

                    //     AnimationUtility.SetObjectReferenceCurve(clip, curveBinding2, matKeyFrames);
                    // }
                    // else
                    // {
                    //     string pngTexPath = resPath + "/" + EditorCommonTool.getSheetDirName(target) + "/" + spriteSheetName + "/" + spriteSheetName + ".png";
                    //     if(File.Exists(pngTexPath))
                    //     {
                    //         ObjectReferenceKeyframe[] matKeyFrames = new ObjectReferenceKeyframe[1];

                    //         matKeyFrames[0] = new ObjectReferenceKeyframe ();
                    //         matKeyFrames[0].time = 0;
                    //         matKeyFrames[0].value = SpriteExtension.getBaseMaterial(t != typeof(SpriteRenderer));

                    //         EditorCurveBinding curveBinding2 = new EditorCurveBinding();
                    //         curveBinding2.type = t;
                    //         curveBinding2.path = curveBindings [j].path;
                    //         if(t == typeof(SpriteRenderer))
                    //         {
                    //             curveBinding2.propertyName = "m_Materials.Array.data[0]";
                    //         }
                    //         else
                    //         {
                    //             curveBinding2.propertyName = "m_Material";
                    //         }

                    //         AnimationUtility.SetObjectReferenceCurve(clip, curveBinding2, matKeyFrames);
                    //     }
                    // }
                
                    AnimationUtility.SetObjectReferenceCurve (clip, curveBindings [j], keyFrame);
                }
            }
        }
	}


    

    [MenuItem("Custom/PrefabTool/ReferenceToSpriteSheet")]
    static void ReferenceToSpriteSheet()
    {
//        MaterialTextureForETC1.SetReferenceToSpriteSheet(MaterialTextureForETC1.SetPrefabReferenceToSpriteSheet4);

        ReferenceSceneToSpriteSheet();
        ReferencePrefabToSpriteSheet();
        ReferenceAnimToSpriteSheet();

        AssetDatabase.Refresh();
        AssetDatabase.SaveAssets();
    }

    [MenuItem("Custom/PrefabTool/CheckPrefabSprite")]
    public static void CheckPrefabSprite()
    {
        string[] prefabDirs = new string[]{ResourcesEx.BundleResDir + "/prefab/ui/"};
        for(int v = 0; v < prefabDirs.Length; v++)
        {
            string[] paths = System.IO.Directory.GetFiles(prefabDirs[v], "*.prefab", System.IO.SearchOption.AllDirectories);
            for(int i = 0; i < paths.Length; i++)
            {
                string path = paths[i];

                string[] temppaths = new string[]{path};
                string[] dependencies = AssetDatabase.GetDependencies(temppaths);

                for(int j = 0; j < dependencies.Length; j++)
                {
                    string dependencePath = dependencies[j];
                    bool src = false;
                    if(src)
                    {

                    }
                    else
                    {
                        if(dependencePath.EndsWith("jpg") || dependencePath.EndsWith("png"))
                        {
                            if(!dependencePath.Contains("/" + EditorCommonTool.getPlatform() + "/"))
                            {
                                Debug.LogError("error_object: " + path);
                                Debug.LogError("error_object_2: " + dependencePath);
                                break;
                            }
                        }
                    }


                }
            }
        }
    }

	// [MenuItem("Custom/PrefabTool/ConvertAudioSourceToSoundEffected")]
	// static void ConvertAudioSourceToSoundEffected()
	// {
    //     string[] paths = System.IO.Directory.GetFiles(ResourcesEx.BundleResDir + "/", "*.prefab", System.IO.SearchOption.AllDirectories);
	// 	for (int i = 0; i < paths.Length; i++)
	// 	{
	// 		string path = paths[i];

	// 		GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
	// 		AudioSource[] sources = prefab.GetComponentsInChildren<AudioSource>();
	// 		for (int j = 0; j < sources.Length; j++)
	// 		{
	// 			AudioSource source = sources[j];
	// 			AudioClip clip = source.clip;
	// 			if (clip != null)
	// 			{
	// 				SoundEffect3d[] effects = prefab.GetComponentsInChildren<SoundEffect3d>();
	// 				for(int k = 0; k < effects.Length; k++)
	// 				{
	// 					GameObject.DestroyImmediate(effects[k], true);
	// 				}
	// 				SoundEffect3d effect = source.gameObject.AddComponent<SoundEffect3d>();
	// 				effect.clip = clip;
	// 			}

	// 			GameObject.DestroyImmediate(source, true);
	// 		}
	// 	}

	// 	AssetDatabase.SaveAssets();
	// 	AssetDatabase.Refresh();
	// }

	[MenuItem("Assets/Custom/PrefabTool/DeleteEmptyNode")]
	static void DeleteEmptyNode()
	{
		EditorCommonTool.ProcessSelectionObjs("*.prefab", (path) =>
			{
				GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);

				while(true)
				{
					bool find = false;
					Transform[] nodes = prefab.GetComponentsInChildren<Transform>();
					for(int i = 0; i < nodes.Length; i++)
					{
						Transform node = nodes[i];
						if(node.childCount == 0)
						{
							Component[] compnents = node.GetComponents<Component>();
							if(compnents.Length <= 1)
							{
								GameObject.DestroyImmediate(node.gameObject, true);
								find = true;
							}
						}
					}

					if(!find)
					{
						break;
					}
				}
			});

		AssetDatabase.SaveAssets();
		AssetDatabase.Refresh();
	}


	public static HashSet<string> GetLuaAssetPathSet(string prefix = null)
	{
		HashSet<string> assetPathSet = new HashSet<string>();
//		System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"=\s*""(.*)""");
        System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"\s*""([^""]*)""");
		string[] paths = System.IO.Directory.GetFiles("Assets/ToLua/Lua/config", "*.lua", System.IO.SearchOption.AllDirectories);
		for (int i = 0; i < paths.Length; i++)
		{
			string path = paths[i];

//            if (path.Contains("clientSkill"))
//            {
//                Debug.LogError("asdf");
//            }
			string content = CommonUtil.fileToString(path);
			System.IO.StringReader reader = new System.IO.StringReader(content);
			while (true)
			{
				string line = reader.ReadLine();
				if (line == null)
				{
					break;
				}

                System.Text.RegularExpressions.MatchCollection matches = regex.Matches(line);
                foreach (System.Text.RegularExpressions.Match match in matches)
                {
                    if (match.Success)
                    {
                        string assetPath = match.Groups[1].Value;

                        if (prefix != null)
                        {
                            if (!assetPath.StartsWith(prefix))
                            {
                                continue;
                            }
                        }

                        assetPathSet.Add(assetPath);
                    }
                }
			}
		}

		return assetPathSet;
	}

	static void ProcessDir(string dirPath, System.Action<string> callBack)
	{
        dirPath = dirPath.Replace("\\", "/");

		int index = dirPath.IndexOf("%d");
		if (index >= 0)
		{
			int preSlashIndex = dirPath.LastIndexOf("/", index);
			int nextSlashIndex = dirPath.IndexOf("/", index);
            if(preSlashIndex < 0 || dirPath.Length <= 0)
            {
                throw new System.Exception("dirPath format error: " + dirPath + "  " + preSlashIndex + "  " + nextSlashIndex);
            }
			
			string preDir = dirPath.Substring(0, preSlashIndex);
			string matchName = "";
			try
			{
				if(nextSlashIndex < 0)
				{
					matchName = dirPath.Substring(preSlashIndex + 1);
				}
				else
				{
					matchName = dirPath.Substring(preSlashIndex + 1, nextSlashIndex - (preSlashIndex + 1));
				}
			}
			catch(System.Exception e)
			{
				Debug.LogException(e);
				return;
			}

			matchName = matchName.Replace("%d", "*");
			string postDir = "";
			if (nextSlashIndex >= 0)
			{
				postDir = dirPath.Substring(nextSlashIndex + 1);
			}

			string[] preDirPaths = System.IO.Directory.GetDirectories(preDir, matchName, System.IO.SearchOption.TopDirectoryOnly);
			for (int i = 0; i < preDirPaths.Length; i++)
			{
				string preDirPath = preDirPaths[i];
				string realDirPath = preDirPath + "/" + postDir;
				if (System.IO.Directory.Exists(realDirPath))
				{
					callBack(realDirPath);
				}
			}
		}
		else
		{
			callBack(dirPath);
		}
	}

	public static HashSet<string> ConvertToRealPath(HashSet<string> assetPathSet)
	{
		HashSet<string> realAssetPathSet = new HashSet<string>();
		foreach (var s in assetPathSet)
		{
			if (string.IsNullOrEmpty(s))
			{
				continue;
			}

//            if (s.Contains ("cursor_effect")) {
//				Debug.LogError (s);
//			}

			string temp = "Assets/" + s;

			string dirPath = "";
			string fileName = "";
//			try
			{
				dirPath = System.IO.Path.GetDirectoryName(temp);
                dirPath = dirPath.Replace("\\", "/");

//                if(!temp.Contains("\\") && dirPath.Contains("\\"))
//                {
//                    throw new System.Exception("dirPath error: " + temp + "  " + dirPath);
//                }
				fileName = System.IO.Path.GetFileName(temp);
			}
//            catch(System)
//			{
//				continue;
//			}



			ProcessDir(dirPath, (realPath) =>
				{
					if(!System.IO.Directory.Exists(realPath))
					{
						return;
					}
					try
					{
						string[] paths = System.IO.Directory.GetFiles(realPath, fileName + ".*", System.IO.SearchOption.TopDirectoryOnly);
						for (int i = 0; i < paths.Length; i++)
						{
							string path = paths[i];
							if (path.EndsWith(".meta"))
							{
								continue;
							}

							if(path.EndsWith(".DS"))
							{
								continue;
							}


							realAssetPathSet.Add(path.Replace("\\", "/"));
						}
					}
					catch
					{
						
					}

				});

		}

		return realAssetPathSet;
	}



	[MenuItem("Custom/PrefabTool/CheckMaterialAndTexture")]
	public static void CheckMaterialAndTexture()
	{
		HashSet<string> assetPathSet = GetLuaAssetPathSet("art/model/");
		HashSet<string> realAssetPathSet = ConvertToRealPath(assetPathSet);

		foreach (var prefabPath in realAssetPathSet)
		{
			string[] dependencedPaths = AssetDatabase.GetDependencies(prefabPath, true);
			for (int i = 0; i < dependencedPaths.Length; i++)
			{
				string dependencedPath = dependencedPaths[i];
				if (dependencedPath.EndsWith(".mat"))
				{
					bool found = false;
					Material mat = AssetDatabase.LoadAssetAtPath<Material>(dependencedPath);
					Shader shader = mat.shader;
					int propCount = ShaderUtil.GetPropertyCount(shader);
					for (int j = 0; j < propCount; j++)
					{
						ShaderUtil.ShaderPropertyType propType = ShaderUtil.GetPropertyType(shader, j);
						if (propType == ShaderUtil.ShaderPropertyType.TexEnv)
						{
							string propName = ShaderUtil.GetPropertyName(shader, j);
							Texture2D tex = mat.GetTexture(propName) as Texture2D;
							if (tex != null)
							{
								string texPath = AssetDatabase.GetAssetPath(tex);
								if (texPath.StartsWith("Assets/terrain"))
								{
									Debug.LogError("terrain mat: " + prefabPath + "  " + dependencedPath);
									found = true;
									break;
								}
							}
						}
					}

					if (found)
					{
						break;
					}
				}
			}
		}
	}



	[MenuItem("Custom/PrefabTool/PrintObjectPoolInfo")]
	static void PrintObjectPoolInfo()
	{
		Debug.LogError(ObjectPool.GetInfo());
	}

    [MenuItem("GameObject/Custom/SaveUIPrefab")]
    static void SavePrefab()
    {
        GameObject selectGo = Selection.activeGameObject;
        if (selectGo == null)
        {
            Debug.LogError("请选中需要Apply的Prefab实例");
            return;
        }
        PrefabType pType = EditorUtility.GetPrefabType(selectGo);
        if (pType != PrefabType.PrefabInstance && pType != PrefabType.DisconnectedPrefabInstance)
        {
            Debug.LogError("选中的实例不是Prefab实例");
            return;
        }

        //这里必须获取到prefab实例的根节点，否则ReplacePrefab保存不了
        GameObject prefabGo = GetPrefabInstanceParent(selectGo);
        UnityEngine.Object prefabAsset = null;
        if (prefabGo != null)
        {
            UIModelPanel[] panels = prefabGo.GetComponentsInChildren<UIModelPanel>();
            for (int i = 0; i < panels.Length; i++)
            {
                panels[i].ResetRenderMaterials();
            }

            prefabAsset = PrefabUtility.GetPrefabParent(prefabGo);
            if (prefabAsset != null)
            {
                PrefabUtility.ReplacePrefab(prefabGo, prefabAsset, ReplacePrefabOptions.ConnectToPrefab);
            }
        }
        AssetDatabase.SaveAssets();
    }

    static GameObject GetPrefabInstanceParent(GameObject go)
    {
        if (go == null)
        {
            return null;
        }
        PrefabType pType = EditorUtility.GetPrefabType(go);
        if (pType != PrefabType.PrefabInstance && pType != PrefabType.DisconnectedPrefabInstance)
        {
            return null;
        }
        if (go.transform.parent == null)
        {
            return go;
        }
        pType = EditorUtility.GetPrefabType(go.transform.parent.gameObject);
        if (pType != PrefabType.PrefabInstance && pType != PrefabType.DisconnectedPrefabInstance)
        {
            return go;
        }
        return GetPrefabInstanceParent(go.transform.parent.gameObject);
    }
    [MenuItem("Custom/GuidToPath")]
    static void GuidToPath()
    {
        string guid = "ba07bfb942ea5aede29dd05af26b3684";
//        string guid = "5bdc918b89d937462069ea7d170dab42";

        Debug.LogError(AssetDatabase.GUIDToAssetPath(guid));
    }

//    [MenuItem("Custom/TestSerialzableField")]
//    static void TestSerialzableField()
//    {
//        GameObject obj = new GameObject();
//        SerializableFieldContainerBehaviour b = obj.AddComponent<SerializableFieldContainerBehaviour>();
//        b.container = new SerializableFieldContainer();
//        b.container.Set("a", 1);
////        b.myObj = new MyObject();
////        b.myObj.n1 = 1;
//
//        PrefabUtility.CreatePrefab("Assets/test_serialize.prefab", obj);
//
//        GameObject.DestroyImmediate(obj);
//    }

//    [MenuItem("Custom/TestSerialzableField2")]
//    static void TestSerialzableField2()
//    {
//        GameObject obj = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/test_serialize.prefab");
//        SerializableFieldContainerBehaviour b = obj.GetComponent<SerializableFieldContainerBehaviour>();
//        Debug.LogError(b.container.Get("a") + "");
//    }

    static System.Type GetType(string typeFullName)
    {
        if (typeFullName == "UnityEngine.Texture2D")
        {
            Debug.Log("sadf");
        }

        System.Type t = System.Type.GetType(typeFullName);
        if (t != null)
        {
            return t;
        }

        foreach (System.Reflection.Assembly assembly in System.AppDomain.CurrentDomain.GetAssemblies())
        {
            t = assembly.GetType(typeFullName);
            if (t != null)
            {
                return t;
            }
        }
        return null;
    }

    [MenuItem("Custom/TestAssetBundleScript")]
    static void TestAssetBundleScript()
    {
        Dictionary<string, List<KeyValuePair<string, string>>> lastMonoScriptInfoMap = CommonUtil.ObjectFromJsonFile<Dictionary<string, List<KeyValuePair<string, string>>>>("Assets" + "/test/" + "monoscript_info.txt");

        HashSet<string> typeSet = new HashSet<string>();
        foreach (var entry in lastMonoScriptInfoMap)
        {
            string classFullName = entry.Key;


            System.Type classType = GetType(classFullName);

            if (classType == null)
            {
                throw new System.Exception("get type failed: " + classFullName);
            }
            
            if (!classType.IsSubclassOf(typeof(Window)))
            {
                continue;
            }

            if (classFullName.StartsWith("UnityEngine."))
            {
                continue;
            }

            if (classType.IsSubclassOf(typeof(UIRect)))
            {
                continue;
            }

            List<KeyValuePair<string, string>> list = entry.Value;
            for (int i = 0; i < list.Count; i++)
            {
                typeSet.Add(list[i].Value);
            }
        }

        HashSet<string> enterQueueSet = new HashSet<string>();
        Queue<string> typeQueue = new Queue<string>(typeSet);
        while (typeQueue.Count > 0)
        {
            string typeName = typeQueue.Dequeue();
            if (enterQueueSet.Contains(typeName))
            {
                continue;
            }
                
            System.Type classType = GetType(typeName);
            if (classType != null)
            {
                if (typeName.StartsWith("UnityEngine."))
                {
                    continue;
                }

                if (classType.IsSubclassOf(typeof(UIRect)))
                {
                    continue;
                }

                if (classType.IsSubclassOf(typeof(UIWidgetContainer)))
                {
                    continue;
                }
            }


            enterQueueSet.Add(typeName);

            List<KeyValuePair<string, string>> list = null;
            if (!lastMonoScriptInfoMap.TryGetValue(typeName, out list))
            {
                continue;
            }

            if (list != null)
            {
                for (int i = 0; i < list.Count; i++)
                {
                    if (!enterQueueSet.Contains(list[i].Value))
                    {
                        string classFullName = list[i].Value;


                        typeQueue.Enqueue(list[i].Value);


                    }
                }
            }
        }

        List<string> nameList = new List<string>(enterQueueSet);
        nameList.Sort();

        string log = "";
        for(int i = nameList.Count - 1; i >= 0; i--)
        {
            string typeFullName = nameList[i];
//            System.Type t = GetType(typeFullName);
            log += nameList[i] + "\n";
        }

        Debug.LogError(log);
    }


//     [MenuItem("Assets/Custom/PrefabTool/SerializeScript")]
//     static void SerializeScriptForSelection()
//     {
//         EditorCommonTool.ProcessSelectionObjs("*", (path) =>
//             {
// //                if(path.EndsWith(".prefab") || path.EndsWith(".unity"))
// //                {
//                     HashSet<string> pathSet = new HashSet<string>();
//                     pathSet.Add(path);
//                     SerializeScriptForPrefab(pathSet, null);
// //                }
// //                else if(path.EndsWith(".asset"))
// //                {
// //                    HashSet<string> pathSet = new HashSet<string>();
// //                    pathSet.Add(path);
// //                    SerializeScriptForScriptableObject(pathSet, null);
// //                }
//             });

//         AssetDatabase.Refresh();
//         AssetDatabase.SaveAssets();
//     }

    // static void SerializeScriptByCmd()
    // {
    //     bool onlyInAppRes = false;
    //     string[] args = System.Environment.GetCommandLineArgs();
    //     for (int i = 0; i < args.Length; i++)
    //     {
    //         string arg = args[i];
    //         if (arg == "-modify_asset")
    //         {
    //             onlyInAppRes = !bool.Parse(args[++i]);
    //         }
    //     }
            
    //     HashSet<string> inAppResPaths = null;
    //     if (onlyInAppRes)
    //     {
    //         inAppResPaths = new HashSet<string>();
    //         string rawFilePath = AssetBundleTool.resPath + "/" + "raw_" + BundleManager.configName + ".json";
    //         BundleConfig config = CommonUtil.ObjectFromJsonFile<BundleConfig>(rawFilePath);
                
    //         foreach (var entry in config.bundles)
    //         {
    //             if(entry.Value.type == BundleType.scene)
    //             {
    //                 inAppResPaths.Add(entry.Value.excluded_assets);

    //                 for (int i = 0; i < entry.Value.excluded_assets.Length; i++)
    //                 {
    //                     string scenePath = entry.Value.excluded_assets[i];
    //                     string[] ds = AssetDatabase.GetDependencies(scenePath, true);
    //                     inAppResPaths.Add(ds);
    //                 }
    //             }
    //         }
    //     }

    //     SerializeScript2(inAppResPaths);
    // }

    [MenuItem("GameObject/Custom/PrefabTool/CompleteDisconnect")]
    static void Disconnect()
    {
        GameObject newObj = GameObject.Instantiate(Selection.activeObject, (Selection.activeObject as GameObject).transform.parent) as GameObject;
        newObj.name = Selection.activeObject.name;

        GameObject.DestroyImmediate(Selection.activeObject, true);
    }

//     [MenuItem("Custom/PrefabTool/SerializeScript")]
//     static void SerializeScript()
//     {
//         HashSet<string> inAppResPaths = null;
// //        if (true)
// //        {
// //            inAppResPaths = new HashSet<string>();
// //            string rawFilePath = AssetBundleTool.resPath + "/" + "raw_" + BundleManager.configName + ".json";
// //            BundleConfig config = CommonUtil.ObjectFromJsonFile<BundleConfig>(rawFilePath);
// //
// //            foreach (var entry in config.bundles)
// //            {
// //                if(entry.Value.type == BundleType.scene)
// //                {
// ////                            inAppResPaths.Add(entry.Value.excluded_assets);
// //
// //                    for (int i = 0; i < entry.Value.excluded_assets.Length; i++)
// //                    {
// //                        string scenePath = entry.Value.excluded_assets[i];
// //
// //                        Queue<string> q = new Queue<string>();
// //                        q.Enqueue(scenePath);
// //                        while (q.Count > 0)
// //                        {
// //                            string ts = q.Dequeue();
// //                            inAppResPaths.Add(ts);
// //
// //                            string[] ds = AssetDatabase.GetDependencies(ts, false);
// //
// //                            for (int j = 0; j < ds.Length; j++)
// //                            {
// //                                string d = ds[j];
// //                                if (d.Contains("LoadingDialog.prefab"))
// //                                {
// //                                    Debug.LogError("adsf");
// //                                }
// //
// //                                if (!inAppResPaths.Contains(d))
// //                                {
// //                                    q.Enqueue(d);
// //                                }
// //                            }
// //                        }
// //                    }
// //                }
// //            }
// //        }

//         SerializeScript2(inAppResPaths);
//     }

//     static void SerializeScript2(HashSet<string> onlyPathSet)
//     {
//         HashSet<string> prefabPathSet = new HashSet<string>();
//         string[] prefabPaths = System.IO.Directory.GetFiles("Assets", "*.prefab", System.IO.SearchOption.AllDirectories);
//         if (onlyPathSet != null)
//         {
//             for (int i = 0; i < prefabPaths.Length; i++)
//             {
//                 string prefabPath = prefabPaths[i];
//                 if (onlyPathSet == null || onlyPathSet.Contains(prefabPath))
//                 {
//                     prefabPathSet.Add(prefabPath);
//                 }
//             }
//         }
//         else
//         {
//             prefabPathSet.Add(prefabPaths);
//         }

//         for (int i = 0; i < EditorBuildSettings.scenes.Length; i++)
//         {
//             EditorBuildSettingsScene scene = EditorBuildSettings.scenes[i];

//             if (!string.IsNullOrEmpty(scene.path))
//             {
//                 if (onlyPathSet == null || onlyPathSet.Contains(scene.path))
//                 {
//                     prefabPathSet.Add(scene.path);
//                 }
//             }
//             else
//             {
//                 throw new System.Exception("scene path is null: " + scene.guid + "    " + scene.path);
//             }
//         }

//         string[] guids = AssetDatabase.FindAssets("t:scriptableobject");
//         for (int i = 0; i < guids.Length; i++)
//         {
//             string p = AssetDatabase.GUIDToAssetPath(guids[i]);
//             if (onlyPathSet != null)
//             {
//                 if (onlyPathSet.Contains(p))
//                 {
//                     prefabPathSet.Add(p);
//                 }
//             }
//             else
//             {
//                 prefabPathSet.Add(p);
//             }
//         }

//         HashSet<System.Type> classSet = SerializeScriptForPrefab(prefabPathSet, onlyPathSet);

//         if (onlyPathSet != null)
//         {
//             string[] scriptPaths = System.IO.Directory.GetFiles(serializableScriptDir, "*.cs", System.IO.SearchOption.AllDirectories);
//             for (int i = 0; i < scriptPaths.Length; i++)
//             {
//                 string sp = scriptPaths[i];
//                 AddSerializableType(sp, classSet);
//             }
//         }

            
// //        HashSet<System.Type> classSet2 = SerializeScriptForScriptableObject(pathSet, onlyPathSet);
// //        classSet.Add(classSet2);

//         AssetDatabase.Refresh();
//         AssetDatabase.SaveAssets();

        
//         {
//             string settingPath = "Assets/ToLua/Editor/CustomSettings.cs";
//             string str = CommonUtil.fileToString(settingPath);

//             foreach(var s in classSet)
//             {
//                 string pattern = @".*\(" + s.Name + @"\).*\n";
//                 str = System.Text.RegularExpressions.Regex.Replace(str, pattern, "");
//             }
//             CommonUtil.stringToFile(settingPath, str);
//         }
        

//         AssetDatabase.Refresh();
//     }

    // public static void DeleteSerializableScriptDir()
    // {
    //     CommonUtil.Delete(serializableScriptDir);
    // }


    public static long GetLocalFileId(Object target)
    {
        PropertyInfo inspectorModeInfo = typeof(SerializedObject).GetProperty ("inspectorMode", BindingFlags.NonPublic | BindingFlags.Instance);
        SerializedObject srlzedObject = new SerializedObject (target);
        //将srlzedObject的inspectorMode值改成InspectorMode.Debug 为了读取m_LocalIdentfierInFile
        inspectorModeInfo.SetValue (srlzedObject, InspectorMode.Debug, null);
        SerializedProperty localIdProp = srlzedObject.FindProperty ("m_LocalIdentfierInFile") ;
        long localIdentiferID = localIdProp.longValue;
        return localIdentiferID;
    }

//    public static void SetLocalFileId(Object target, long newLocalId)
//    {
//        PropertyInfo inspectorModeInfo = typeof(SerializedObject).GetProperty ("inspectorMode", BindingFlags.NonPublic | BindingFlags.Instance);
//        SerializedObject srlzedObject = new SerializedObject (target);
//        //将srlzedObject的inspectorMode值改成InspectorMode.Debug 为了读取m_LocalIdentfierInFile
//        inspectorModeInfo.SetValue (srlzedObject, InspectorMode.Debug, null);
//        SerializedProperty localIdProp = srlzedObject.FindProperty ("m_LocalIdentfierInFile") ;
//        localIdProp.longValue = newLocalId;
//    }

    // static bool isSerializableType(string scriptPath)
    // {
    //     if (scriptPath == null)
    //     {
    //         return false;
    //     }

    //     if (!scriptPath.StartsWith(serializableScriptDir))
    //     {
    //         return false;
    //     }
            
    //     MonoScript script = AssetDatabase.LoadAssetAtPath<MonoScript>(scriptPath);
    //     System.Type t = script.GetClass();

    //     if((t == typeof(ISerializableFieldContainer)) || t.IsAssignableFrom(typeof(ISerializableFieldContainer)))
    //     {
    //         return false;
    //     }

    //     if (t.IsSubclassOf(typeof(ScriptableObject)))
    //     {
    //         return true;
    //     }

    //     if (t.IsSubclassOf(typeof(Window)))
    //     {
    //         return true;
    //     }

    //     if(t == typeof(LuaMonoBehaviour) || t.IsSubclassOf(typeof(LuaMonoBehaviour)))
    //     {
    //         return false;
    //     }

    //     return true;
    // }

//     static int ReplaceWithDataContainer(Object obj, HashSet<System.Type> typeSet, bool onlyCheck = false)
//     {
//         int c = 0;
//         if (obj is GameObject)
//         {
//             GameObject prefab = obj as GameObject;

// //            Window[] wins = prefab.GetComponentsInChildren<Window>(true);
// //            for(int i = 0; i < wins.Length; i++)
// //            {
// //                Window win = wins[i];
// //                if (win != null)
// //                {
// //                    if (win.GetType() != typeof(Window))
// //                    {
// //                        var winObj = win.gameObject;
// //                        c++;
// //                        if(!onlyCheck)
// //                        {
// //                            SerializableFieldContainerBehaviour container = winObj.GetComponent<SerializableFieldContainerBehaviour>();
// //                            if (container == null)
// //                            {
// //                                container = winObj.AddComponent<SerializableFieldContainerBehaviour>();
// //                            }
// //
// //
// //                            Object[] objs = null;
// //                            byte[] data = SerializableFieldContainerHelper.WriteToBytes(win, out objs, typeSet);
// //                            container.unityObjs = objs;
// //                            container.data = data;
// //
// //
// //                            typeSet.Add(win.GetType());
// //
// //
// //
// //                            Window[] ws = winObj.GetComponents<Window>();
// //                            int index = System.Array.FindIndex(ws, (a) => {return a.GetType() == typeof(Window); });
// //
// //                            if (index < 0)
// //                            {
// //                                winObj.AddComponent<Window>();
// //                            }
// //                        }
// //                    }
// //                }
// //            }
                
//             MonoBehaviour[] behaviours = prefab.GetComponentsInChildren<MonoBehaviour>(true);
//             for (int i = behaviours.Length - 1; i >= 0; i--)
//             {
//                 MonoBehaviour behaviour = behaviours[i];
//                 if (behaviour == null)
//                 {
//                     continue;
//                 }

//                 MonoScript script = MonoScript.FromMonoBehaviour(behaviour);
//                 string scripPath = AssetDatabase.GetAssetPath(script);

//                 if (!isSerializableType(scripPath))
//                 {
//                     continue;
//                 }

//                 c++;

//                 if(!onlyCheck)
//                 {
//                     SerializableFieldContainerBehaviour container = null;
//                     SerializableFieldContainerBehaviour[] containers = behaviour.gameObject.GetComponents<SerializableFieldContainerBehaviour>();
//                     for(int j = 0; j < containers.Length; j++)
//                     {
//                         string className = containers[j].GetFieldDictionary().className;
//                         if(className == behaviour.GetType().Name)
//                         {
//                             container = containers[j];
//                             break;
//                         }
//                     }

//                     if(container == null)
//                     {
//                         container = behaviour.gameObject.AddComponent<SerializableFieldContainerBehaviour>();
//                     }


//                     Object[] objs = null;
//                     byte[] data = SerializableFieldContainerHelper.WriteToBytes(behaviour, out objs, typeSet);
//                     container.unityObjs = objs;
//                     container.data = data;



//                     typeSet.Add(behaviour.GetType());

//                     if(behaviour.GetType().IsSubclassOf(typeof(Window)))
//                     {
//                         Window[] ws = behaviour.gameObject.GetComponents<Window>();
//                         int index = System.Array.FindIndex(ws, (a) => {return a.GetType() == typeof(Window); });

//                         if (index < 0)
//                         {
//                             behaviour.gameObject.AddComponent<Window>();
//                         }
//                     }
//                 }
//             }

//         }

//         return c;
//     }

//     static void DeleteReplacedComponent(object obj)
//     {
//         if(obj is UnityEngine.SceneManagement.Scene)
//         {
//             UnityEngine.SceneManagement.Scene scene = (UnityEngine.SceneManagement.Scene)obj;
//             GameObject[] rootObjs = scene.GetRootGameObjects();

//             for (int i = 0; i < rootObjs.Length; i++)
//             {
//                 GameObject rootObj = rootObjs[i];
//                 DeleteReplacedComponent(rootObj);
//             }
//         }
//         else if (obj is GameObject)
//         {
//             GameObject prefab = obj as GameObject;
//             Dictionary<Object, Object> objMap = new Dictionary<Object, Object>();

//             string path = AssetDatabase.GetAssetPath(prefab);

//             SerializableFieldContainerBehaviour[] behaviours = prefab.GetComponentsInChildren<SerializableFieldContainerBehaviour>(true);
//             for (int i = behaviours.Length - 1; i >= 0; i--)
//             {
//                 SerializableFieldContainerBehaviour behaviour = behaviours[i];
//                 string clsName = behaviour.GetFieldDictionary().className;
//                 Object c = behaviour.gameObject.GetComponent(clsName);
//                 GameObject.DestroyImmediate(c, true);
//             }

// //            MonoBehaviour[] behaviours = prefab.GetComponentsInChildren<MonoBehaviour>(true);
// //            for (int i = behaviours.Length - 1; i >= 0; i--)
// //            {
// //                MonoBehaviour behaviour = behaviours[i];
// //                if (behaviour == null || behaviour.GetType() == typeof(LuaMonoBehaviour) || behaviour.GetType().IsSubclassOf(typeof(LuaMonoBehaviour)) || behaviour.GetType() == typeof(SerializableFieldContainerBehaviour) || behaviour.GetType().IsSubclassOf(typeof(SerializableFieldContainerBehaviour)))
// //                {
// //                    continue;
// //                }
// //
// //                MonoScript script = MonoScript.FromMonoBehaviour(behaviour);
// //                string scripPath = AssetDatabase.GetAssetPath(script);
// //
// //                if (scripPath.StartsWith(serializableScriptDir))
// //                {
// //                    GameObject.DestroyImmediate(behaviour, true);
// //                }
// //            }
//         }
//     }

    // static void AddSerializableType(string path, HashSet<System.Type> typeSet)
    // {
    //     if (path.EndsWith(".cs"))
    //     {
    //         if (isSerializableType(path))
    //         {
    //             MonoScript script = AssetDatabase.LoadAssetAtPath<MonoScript>(path);
    //             SerializableFieldContainerHelper.AddSerializableType(script.GetClass(), typeSet);
    //         }
    //     }
    // }

    public static HashSet<string> GetDirectDependenicesQuick(string path, Dictionary<string, string> guidToPathMap)
    {
        System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"guid:\s*([^,\}]+)");
        string str = CommonUtil.fileToString(path);

        HashSet<string> dset = new HashSet<string>();
        System.Text.RegularExpressions.MatchCollection ms = regex.Matches(str);
        for (int i = 0; i < ms.Count; i++)
        {
            System.Text.RegularExpressions.Match m = ms[i];
            string guid = m.Groups[1].Value;
            string assetPath = null;
            if (guidToPathMap != null)
            {
                if (!guidToPathMap.TryGetValue(guid, out assetPath))
                {
                    assetPath = AssetDatabase.GUIDToAssetPath(guid);
                    guidToPathMap.Add(guid, assetPath);
                }
            }
            else
            {
                assetPath = AssetDatabase.GUIDToAssetPath(guid);
            }

            if (!string.IsNullOrEmpty(assetPath))
            {
                dset.Add(assetPath);
            }
        }

        return dset;
    }

    // public static string serializableScriptDir = "Assets/Scripts/SerializableScript/";
    // public static string SerializadDataDirName = "serialized_data";

    // static Dictionary<long, long> GetObjectLocalFieldMap(Object obj)
    // {
    //     Dictionary<long, long> localIdentifierMap = new Dictionary<long, long>();
    //     if(obj is GameObject)
    //     {
    //         GameObject prefabObj = obj as GameObject;
    //         SerializableFieldContainerBehaviour[] sfcbs = prefabObj.GetComponentsInChildren<SerializableFieldContainerBehaviour>(true);
    //         for(int i = 0; i < sfcbs.Length; i++)
    //         {
    //             SerializableFieldContainerBehaviour b = sfcbs[i];
    //             string clsName = b.GetFieldDictionary().className;
    //             Object tc = b.gameObject.GetComponent(clsName);

    //             long localFileId0 = GetLocalFileId(tc);
    //             long localFileId1 = GetLocalFileId(b);

    //             localIdentifierMap.Add(localFileId0, localFileId1);
    //         }
    //     }
    //     return localIdentifierMap;
    // }

//     static HashSet<System.Type> SerializeScriptForPrefab(HashSet<string> prefabPaths, HashSet<string> onlyPathSet)
//     {
//         //{fileID: 4512020719875828,
//         //{fileID: 4512020719875828}

//         string oldScenePath = EditorSceneManager.GetActiveScene().path;

//         Dictionary<string, string> guidToPathMap = new Dictionary<string, string>();
//         Dictionary<string, HashSet<string>> prefabMap = new Dictionary<string, HashSet<string>>();
//         foreach(var path in prefabPaths)
//         {
//             HashSet<string> dset = GetDirectDependenicesQuick(path, guidToPathMap);
//             prefabMap.Add(path, dset);
//         }

//         HashSet<System.Type> typeSet = new HashSet<System.Type>();

//         Dictionary<string, Dictionary<long, long>> replaceFileIdMap = new Dictionary<string, Dictionary<long, long>>();

//         string tempDataAssetPath = "Assets/temp_data.asset";

//         HashSet<string> processedPaths = new HashSet<string>();
//         foreach (var prefabPath in prefabPaths)
//         {
//             bool found = false;
//             HashSet<string> dset = prefabMap[prefabPath];
//             foreach (var p in dset)
//             {
//                 if (p.StartsWith(serializableScriptDir))
//                 {
//                     found = true;
//                     break;
//                 }
//             }

//             if (!found)
//             {
//                 continue;
//             }

//             processedPaths.Add(prefabPath);

//             if (onlyPathSet == null || onlyPathSet.Contains(prefabPath))
//             {
// 				if (prefabPath.EndsWith(".prefab"))
// 				{
// 					bool needInstance = false;
// 					if(needInstance)
// 					{
//                         GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
//                         if(ReplaceWithDataContainer(prefab, typeSet, true) > 0)
//                         {
//     						GameObject obj = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
//     						if (obj == null)
//     						{
//     							Debug.LogError("InstantiatePrefab prefab failed: " + prefabPath);
//     							continue;
//     						}

//     						int count = ReplaceWithDataContainer(obj, typeSet);
//                             if (count > 0)
//                             {
//     //                            PrefabUtility.ReplacePrefab(obj, prefab, ReplacePrefabOptions.Default);
//                                 PrefabUtility.ApplyPrefabInstance(obj, InteractionMode.AutomatedAction);

//                                 Dictionary<long, long> localIdentifierMap = GetObjectLocalFieldMap(prefab);
//                                 replaceFileIdMap.Add(prefabPath, localIdentifierMap);
//                             }

//                             GameObject.DestroyImmediate(obj);
//                         }
// 					}
// 					else
// 					{
// //                        GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);

//                         GameObject prefab = PrefabUtility.LoadPrefabContents(prefabPath);
// //                        GameObject prefab = PrefabUtility.LoadPrefabContentsIntoPreviewScene(prefabPath, EditorSceneManager.GetActiveScene());

//                         int count = ReplaceWithDataContainer(prefab, typeSet);
//                         if (count > 0)
// 						{
//                             PrefabUtility.SaveAsPrefabAsset(prefab, prefabPath);
// //                            PrefabUtility.SavePrefabAsset(prefab);

//                             Dictionary<long, long> localIdentifierMap = GetObjectLocalFieldMap(prefab);
// 							replaceFileIdMap.Add(prefabPath, localIdentifierMap);
// 						}
//                         PrefabUtility.UnloadPrefabContents(prefab);
// 					}
// 				}
//                 else if (prefabPath.EndsWith(".unity"))
//                 {
//                     EditorSceneManager.OpenScene(prefabPath);
//                     GameObject[] rootObjs = EditorSceneManager.GetActiveScene().GetRootGameObjects();
//                     Dictionary<long, long> localIdentifierMap = new Dictionary<long, long>();
//                     for (int i = 0; i < rootObjs.Length; i++)
//                     {
//                         GameObject rootObj = rootObjs[i];
//                         Transform[] ts = rootObj.GetComponentsInChildren<Transform>(true);
//                         for (int j = 0; j < ts.Length; j++)
//                         {
//                             PrefabUtility.DisconnectPrefabInstance(ts[j].gameObject);
//                         }


//                         int count = ReplaceWithDataContainer(rootObj, typeSet);
//                         if (count > 0)
//                         {
//                             Dictionary<long, long> localIdentifierMap2 = GetObjectLocalFieldMap(rootObj);
//                             foreach (var entry in localIdentifierMap2)
//                             {
//                                 localIdentifierMap.Add(entry.Key, entry.Value);
//                             }
//                         }
//                     }

//                     if (localIdentifierMap.Count > 0)
//                     {
//                         replaceFileIdMap.Add(prefabPath, localIdentifierMap);
//                     }

//                     EditorSceneManager.SaveScene(EditorSceneManager.GetActiveScene());
//                 }
//                 else if (prefabPath.EndsWith(".asset"))
//                 {
//                     ScriptableObject scriptableObj = AssetDatabase.LoadAssetAtPath<ScriptableObject>(prefabPath);

//                     MonoScript monoScript = MonoScript.FromScriptableObject(scriptableObj);
//                     if (monoScript == null)
//                     {
//                         continue;
//                     }

//                     string scriptPath = AssetDatabase.GetAssetPath(monoScript);
//                     if (!isSerializableType(scriptPath))
//                     {
//                         continue;
//                     }

//                     SerializableFieldContainerScriptableObject container = new SerializableFieldContainerScriptableObject();

//                     Object[] objs = null;
//                     byte[] data = SerializableFieldContainerHelper.WriteToBytes(scriptableObj, out objs, typeSet);
//                     container.unityObjs = objs;
//                     container.data = data;

//                     AssetDatabase.CreateAsset(container, tempDataAssetPath);

//                     CommonUtil.Copy(tempDataAssetPath, prefabPath);


//                     typeSet.Add(scriptableObj.GetType());
//                 }
//             }
// //            else
// //            {
// //                if (onlyPathSet != null)
// //                {
// //                    foreach (var p in dset)
// //                    {
// //                        AddSerializableType(p, typeSet);
// //                    }
// //                }
// //            }
//         }
        
//         AssetDatabase.DeleteAsset(tempDataAssetPath);

//         AssetDatabase.SaveAssets();


//         foreach (var entry in replaceFileIdMap)
//         {
//             string path = entry.Key;
//             Dictionary<long, long> localIdentifierMap = entry.Value;

//             string str = CommonUtil.fileToString(path);

//             foreach (var entry2 in localIdentifierMap)
//             {
//                 string s0 = "&" + entry2.Key + "\n";
//                 string s1 = "&" + entry2.Value + "\n";
//                 string s2 = "&temp" + entry2.Key + "temp\n";
//                 str = str.Replace(s0, s2);
//                 str = str.Replace(s1, s0);
//                 str = str.Replace(s2, s1);
//             }

//             CommonUtil.stringToFile(path, str);


//             //            string guid = AssetDatabase.AssetPathToGUID(path);
// //            foreach(var path2 in prefabPaths)
// //            {
// //                HashSet<string> dset = prefabMap[path2];
// //
// //                if (!dset.Contains(path) && path2 != path)
// //                {
// //                    continue;
// //                }
// //
// //                string str = CommonUtil.fileToString(path2);
// //
// //                foreach (var entry2 in localIdentifierMap)
// //                {
// //                    string s0 = "{fileID: " + entry2.Key;
// //                    string s1 = "{fileID: " + entry2.Value;
// //
// //                    if (path2 != path)
// //                    {
// //                        s0 += ", guid: " + guid + ",";
// //                        s1 += ", guid: " + guid + ",";
// //                    }
// //                    else
// //                    {
// //                        s0 += "}";
// //                        s1 += "}";
// //                    }
// //
// //                    str = str.Replace(s0, s1);
// //                }
// //
// //                CommonUtil.stringToFile(path2, str);

//                 //                    MonoBehaviour[] behComs = dset.Key.GetComponentsInChildren<MonoBehaviour>(true);
//                 //                    for (int u = 0; u < behComs.Length; u++)
//                 //                    {
//                 //                        MonoBehaviour b = behComs[u];
//                 //
//                 //                        if (b == null)
//                 //                        {
//                 //                            continue;
//                 //                        }
//                 //
//                 //                        System.Type t = b.GetType();
//                 //                        System.Reflection.FieldInfo[] fields = t.GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
//                 //                        for (int k = 0; k < fields.Length; k++)
//                 //                        {
//                 //                            System.Reflection.FieldInfo field = fields[k];
//                 //                            if (field.FieldType == typeof(Object))
//                 //                            {
//                 //                                Object obj = field.GetValue(b) as Object;
//                 //                                if(objMap.ContainsKey(obj))
//                 //                                {
//                 //                                    obj = objMap[obj];
//                 //
//                 //                                    field.SetValue(b, obj);
//                 //                                }
//                 //                            }
//                 //                            else if (field.FieldType == typeof(Object[]))
//                 //                            {
//                 //                                bool changed = false;
//                 //                                Object[] objs = field.GetValue(b) as Object[];
//                 //                                for (int m = 0; m < objs.Length; m++)
//                 //                                {
//                 //                                    Object obj = objs[m];
//                 //                                    if(objMap.ContainsKey(obj))
//                 //                                    {
//                 //                                        objs[m] = objMap[obj];
//                 //                                        changed = true;
//                 //                                    }
//                 //                                }
//                 //
//                 //                                if (changed)
//                 //                                {
//                 //                                    field.SetValue(b, objs);
//                 //                                }
//                 //                            }
//                 //                        }
// //            }
//         }


//         AssetDatabase.Refresh();


//         foreach (var prefabPath in processedPaths)
//         {
//             if (onlyPathSet == null || onlyPathSet.Contains(prefabPath))
//             {
//                 if (prefabPath.EndsWith(".prefab"))
//                 {
// //                    GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);

//                     GameObject prefab = PrefabUtility.LoadPrefabContents(prefabPath);
// //                    GameObject prefab = PrefabUtility.LoadPrefabContentsIntoPreviewScene(prefabPath, EditorSceneManager.GetActiveScene());

//                     DeleteReplacedComponent(prefab);

//                     PrefabUtility.SaveAsPrefabAsset(prefab, prefabPath);
// //                    PrefabUtility.SavePrefabAsset(prefab);

//                     PrefabUtility.UnloadPrefabContents(prefab);


//                 }
//                 else if (prefabPath.EndsWith(".unity"))
//                 {
//                     Debug.Log("ready to open scene" + prefabPath);
//                     EditorSceneManager.OpenScene(prefabPath);
//                     DeleteReplacedComponent(EditorSceneManager.GetActiveScene());
//                     EditorSceneManager.SaveScene(EditorSceneManager.GetActiveScene());
//                 }
//             }
//         }

//         if (oldScenePath != EditorSceneManager.GetActiveScene().path)
//         {
//             if (string.IsNullOrEmpty(oldScenePath))
//             {
//                 EditorSceneManager.NewScene(NewSceneSetup.EmptyScene);
//             }
//             else
//             {
//                 EditorSceneManager.OpenScene(oldScenePath);
//             }
//         }

//         return typeSet;
//     }






    [MenuItem("Assets/Custom/PrefabTool/testAmibent")]
    public static void testAmibent()
    {
        RenderSettings.ambientLight = Color.white;
    }

    


    [MenuItem("Custom/PrefabTool/TestParticleInfo")]
    public static void TestParticleInfo()
    {
        ParticleSystem[] ps = GameObject.FindObjectsOfType<ParticleSystem>();
        for (int i = 0; i < ps.Length; i++)
        {
            ParticleSystem p = ps[i];
            ParticleSystemRenderer pr = p.GetComponent<ParticleSystemRenderer>();

            Debug.LogError(p.name + "  " + p.isPlaying + " | " + pr + "  " + pr.enabled +"  " + p.particleCount + "  " + p.main.maxParticles);
        }
    }

    [MenuItem("Assets/Custom/PrefabTool/FixParticleSystemScaleTypeToHierarchy")]
    public static void FixParticleSystemScaleTypeToHierarchy()
    {
        EditorCommonTool.ProcessSelectionObjs("*.prefab", (path) =>
            {
                GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
                if(prefab == null)
                {
                    Debug.LogError("load prefab failed: " + path);
                    return;
                }

                ParticleSystem[] ps = prefab.GetComponentsInChildren<ParticleSystem>(true);
                for(int i = 0; i < ps.Length; i++)
                {
                    ParticleSystem p = ps[i];
                    ParticleSystem.MainModule main = p.main;
                    main.scalingMode = ParticleSystemScalingMode.Hierarchy;
//                    p.main = main;
                }
            });

        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }

    [MenuItem("Custom/PrefabTool/DisableModelReadable")]
    public static void DisableModelReadable()
    {
        HashSet<string> allAssetPaths = new HashSet<string>();

        string[] prefabPaths = new string[]{"Assets/BundleRes/art", "Assets/BundleRes/terrain", "Assets/BundleRes/prefab"};
        //        string[] prefabPaths = new string[]{"Assets/BundleRes/img_font"};
        for(int i = 0; i < prefabPaths.Length; i++)
        {
            string prefabPath = prefabPaths[i];
            string[] filePaths = System.IO.Directory.GetFiles(prefabPath, "*", System.IO.SearchOption.AllDirectories);

            allAssetPaths.Add(AssetDatabase.GetDependencies(filePaths));
        }

        //        string diff = CommonUtil.fileToString("diff.txt");
        //        string[] usedPaths = diff.Split('\n');
        //        HashSet<string> usedPathSet = new HashSet<string>(usedPaths);

        foreach(var s in allAssetPaths)
        {
            string filePath = s;
            //            if(usedPathSet.Contains(filePath))
            //            {
            //                continue;
            //            }

            string ext = System.IO.Path.GetExtension(filePath);
            if(ext == ".prefab" || ext == ".mat" || ext == ".png" || ext == ".jpg" || ext == ".tga")
            {
                continue;
            }

            ModelImporter importer = ModelImporter.GetAtPath(filePath) as ModelImporter;
            if(importer != null)
            {
                //                importer.isReadable = false;
                //                importer.SaveAndReimport();

                string meteFilePath = filePath + ".meta";
                string content = CommonUtil.fileToString(meteFilePath);

                if(importer.isReadable)
                {
                    string a = "isReadable: 1";
                    string b = "isReadable: 0";

                    content = content.Replace(a, b);
                    CommonUtil.stringToFile(meteFilePath, content);
                }


                if(importer.importBlendShapes)
                {
                    string a = "importBlendShapes: 1";
                    string b = "importBlendShapes: 0";

                    content = content.Replace(a, b);
                    CommonUtil.stringToFile(meteFilePath, content);
                }
            }
        }
    }

    static bool DeleteMissingScriptForGameObject(GameObject prefab)
    {
        if(prefab == null)
        {
            return false;
        }

        bool foundNull = false;
        Component[] components2 = prefab.GetComponentsInChildren<Component>(true);
        for(int i = 0; i < components2.Length; i++)
        {
            if(components2[i] == null)
            {
                foundNull = true;
                break;
            }
        }

        if(!foundNull)
        {
            return false;
        }

        int c = 0;
        Queue<Transform> queue = new Queue<Transform>();
        queue.Enqueue(prefab.transform);


        while(queue.Count > 0)
        {
            Transform t = queue.Dequeue();

            var serializedObject = new SerializedObject(t.gameObject);
            var prop = serializedObject.FindProperty("m_Component");
            int r = 0;

            var components = t.gameObject.GetComponents<Component>();
            for (int j = 0; j < components.Length; j++)
            {
                if (components[j] == null)
                {
                    prop.DeleteArrayElementAtIndex(j - r);
                    r++;
                    c++;
                }
            }

            if(r > 0)
            {
                serializedObject.ApplyModifiedProperties();
            }

            for(int i = 0; i < t.childCount; i++)
            {
                queue.Enqueue(t.GetChild(i));
            }
        }

        return c > 0;
    }

    static bool DeleteMissingScriptForPrefab(string prefabPath)
    {
        bool useInstance = true;
        GameObject prefab = null;
        GameObject oldPrefab = null;
        try
        {
            if(useInstance)
            {
                oldPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
                if(oldPrefab != null)
                {
                    prefab = PrefabUtility.InstantiatePrefab(oldPrefab) as GameObject;
                }
            }
            else
            {
                prefab = PrefabUtility.LoadPrefabContents(prefabPath);
            }
        }
        catch(System.Exception e)
        {
            return false;
        }


        bool ret = DeleteMissingScriptForGameObject(prefab);
        if(!ret)
        {
            if(useInstance)
            {
                GameObject.DestroyImmediate(prefab);
            }
            else
            {
                PrefabUtility.UnloadPrefabContents(prefab);
            }

            return false;
        }


        if(useInstance)
        {
            if (ret)
            {
                PrefabUtility.ReplacePrefab(prefab, oldPrefab, ReplacePrefabOptions.Default);
            }
            GameObject.DestroyImmediate(prefab);
        }
        else
        {
            if (ret)
            {
                PrefabUtility.SaveAsPrefabAsset(prefab, prefabPath);
            }

            PrefabUtility.UnloadPrefabContents(prefab);
        }


        return ret;



        //        Component[] cs = prefab.GetComponentsInChildren<Component>(true);
        //        for(int k = 0; k < cs.Length; k++)
        //        {
        //            if(cs[k] == null)
        //            {
        //                Debug.LogError(prefabPath);
        //                break;
        //            }
        //        }
        //        PrefabUtility.UnloadPrefabContents(prefab);
        //
        //        return false;
    }

    [MenuItem("Custom/PrefabTool/DeleteMissingScript")]
    public static void DeleteMissingScript()
    {
        HashSet<string> allAssetPaths = new HashSet<string>();




        EditorCommonTool.ProcessAllScene((path) =>
            {
                bool ret = false;
                GameObject[] rootObjs = EditorSceneManager.GetActiveScene().GetRootGameObjects();
                for(int i = 0; i < rootObjs.Length; i++)
                {
                    GameObject obj = rootObjs[i];
                    if(DeleteMissingScriptForGameObject(obj))
                    {
                        ret = true;
                    }
                }

                if(ret)
                {
                    allAssetPaths.Add(AssetDatabase.GetDependencies(path));
                    EditorSceneManager.SaveScene(EditorSceneManager.GetActiveScene());
                }
            });

        string[] prefabPaths = new string[]{"Assets/BundleRes/art", "Assets/BundleRes/terrain", "Assets/BundleRes/prefab"};
        for(int i = 0; i < prefabPaths.Length; i++)
        {
            string prefabPath = prefabPaths[i];
            string[] filePaths = System.IO.Directory.GetFiles(prefabPath, "*", System.IO.SearchOption.AllDirectories);

            allAssetPaths.Add(AssetDatabase.GetDependencies(filePaths));
        }

        foreach(var s in allAssetPaths)
        {
            string prefabPath = s;
            string ext = System.IO.Path.GetExtension(prefabPath);
            if(ext != ".prefab")
            {
                continue;
            }

            DeleteMissingScriptForPrefab(prefabPath);

            if(prefabPath.Contains("/BundleRes/"))
            {
                string newPath = prefabPath.Replace("/BundleRes/", "/");
                DeleteMissingScriptForPrefab(newPath);
            }
        }
    }


    [MenuItem("Custom/PrefabTool/ChangeUIPanelExOrder")]
    public static void ChangeUIPanelExOrder()
    {
        HashSet<string> allAssetPaths = new HashSet<string>();



        string[] prefabPaths = new string[]{"Assets/BundleRes/prefab"};
        for(int i = 0; i < prefabPaths.Length; i++)
        {
            string prefabPath = prefabPaths[i];
            string[] filePaths = System.IO.Directory.GetFiles(prefabPath, "*", System.IO.SearchOption.AllDirectories);

            allAssetPaths.Add(AssetDatabase.GetDependencies(filePaths));
        }

        foreach(var s in allAssetPaths)
        {
            string prefabPath = s;
            string ext = System.IO.Path.GetExtension(prefabPath);
            if(ext != ".prefab")
            {
                continue;
            }

            ChangeUIPanelExOrderForPrefab(prefabPath);

            if(prefabPath.Contains("/BundleRes/"))
            {
                string newPath = prefabPath.Replace("/BundleRes/", "/");
                ChangeUIPanelExOrderForPrefab(newPath);
            }
        }
    }
    static bool ChangeUIPanelExOrderForPrefab(string prefabPath)
    {
        bool useInstance = true;
        GameObject prefab = null;
        GameObject oldPrefab = null;
        try
        {
            if(useInstance)
            {
                oldPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
                if(oldPrefab != null)
                {
                    prefab = PrefabUtility.InstantiatePrefab(oldPrefab) as GameObject;
                }
            }
            else
            {
                prefab = PrefabUtility.LoadPrefabContents(prefabPath);
            }
        }
        catch(System.Exception e)
        {
            return false;
        }


        bool ret = ChangeUIPanelExOrderGameObject(prefab);
        if(!ret)
        {
            if(useInstance)
            {
                GameObject.DestroyImmediate(prefab);
            }
            else
            {
                PrefabUtility.UnloadPrefabContents(prefab);
            }

            return false;
        }


        if(useInstance)
        {
            if (ret)
            {
                PrefabUtility.ReplacePrefab(prefab, oldPrefab, ReplacePrefabOptions.Default);
            }
            GameObject.DestroyImmediate(prefab);
        }
        else
        {
            if (ret)
            {
                PrefabUtility.SaveAsPrefabAsset(prefab, prefabPath);
            }

            PrefabUtility.UnloadPrefabContents(prefab);
        }


        return ret;



        //        Component[] cs = prefab.GetComponentsInChildren<Component>(true);
        //        for(int k = 0; k < cs.Length; k++)
        //        {
        //            if(cs[k] == null)
        //            {
        //                Debug.LogError(prefabPath);
        //                break;
        //            }
        //        }
        //        PrefabUtility.UnloadPrefabContents(prefab);
        //
        //        return false;
    }
    static bool ChangeUIPanelExOrderGameObject(GameObject prefab)
    {
        if(prefab == null)
        {
            return false;
        }
        bool foundNull = false;
        UIPanel[] components2 = prefab.GetComponentsInChildren<UIPanel>(true);
        for(int i = 0; i < components2.Length; i++)
        {
            if(components2[i] != null)
            {
                Debug.LogError("111111");
                components2[i].useSortingOrder = true;
                foundNull = true;
            }
        }

        if(!foundNull)
        {
            return false;
        }

        // int c = 0;
        // Queue<Transform> queue = new Queue<Transform>();
        // queue.Enqueue(prefab.transform);


        // while(queue.Count > 0)
        // {
        //     Transform t = queue.Dequeue();

        //     var serializedObject = new SerializedObject(t.gameObject);
        //     var prop = serializedObject.FindProperty("m_Component");
        //     int r = 0;

        //     var components = t.gameObject.GetComponents<Component>();
        //     for (int j = 0; j < components.Length; j++)
        //     {
        //         if (components[j] == null)
        //         {
        //             prop.DeleteArrayElementAtIndex(j - r);
        //             r++;
        //             c++;
        //         }
        //     }

        //     if(r > 0)
        //     {
        //         serializedObject.ApplyModifiedProperties();
        //     }

        //     for(int i = 0; i < t.childCount; i++)
        //     {
        //         queue.Enqueue(t.GetChild(i));
        //     }
        // }

        return true;
    }
}

